package com.xq.model.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xq.config.properties.ManageProperties;
import com.xq.model.entity.TBaseDataRecord;
import com.xq.model.entity.TBaseStationState;
import com.xq.model.entity.TBaseSurfMin;
import com.xq.model.mapper.TBaseDataRecordMapper;
import com.xq.model.service.ITBaseDataRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xq.model.service.ITBaseStationInfoService;
import com.xq.model.service.ITBaseStationStateService;
import com.xq.model.service.ITBaseSurfMinService;
import com.xq.model.vo.DataRecordAddVo;
import com.xq.model.vo.DataRecordEditVo;
import com.xq.utils.DateUtils;
import com.xq.utils.HttpUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 数据记录表 服务实现类
 * </p>
 *
 * @author xu
 * @since 2021-09-13
 */
@Service
public class TBaseDataRecordServiceImpl extends ServiceImpl<TBaseDataRecordMapper, TBaseDataRecord> implements ITBaseDataRecordService {
    @Resource
    private ITBaseStationInfoService stationInfoService;
    @Resource
    private ITBaseSurfMinService surfMinService;
    @Resource
    private ITBaseStationStateService stationStateService;
    @Resource
    private ManageProperties manageProperties;

    @Override
    public void postDataRecord(TBaseDataRecord dataRecord) throws IOException {
        String jsonStr = JSON.toJSONString(dataRecord);
        HttpUtils.sendPostJson(manageProperties.getHost()+manageProperties.getDataRecordPath(),jsonStr);
    }

    @Override
    public void updateDataRecord(DataRecordEditVo editVo) throws IOException {
        // 获取新的超时集合
        List<String> overList = editVo.getOverTimeStationIdCList();
        // 如果集合没有 那就返回吧
        if(overList == null || overList.size() == 0){
            return;
        }
        LambdaQueryWrapper<TBaseDataRecord> lqw = Wrappers.lambdaQuery();
        lqw
                .eq(true,TBaseDataRecord::getDataType,editVo.getDataType())
                .eq(true,TBaseDataRecord::getTimes,editVo.getTimes());

        TBaseDataRecord dataRecord = getOne(lqw);

        // 获取所有站点 IDC 集合
        List<String> stationIdList =  stationInfoService.allStationIdC();

        // 获取实报
        String oldRealStr = dataRecord.getRealReportStationIdCList();
        // 获取以前的实报集合
        List<String> real = Stream.of(oldRealStr.split(",")).collect(Collectors.toList());
        // 获取现在的实报集合 即加入超时的集合
        real.addAll(overList);

        // 获取超时
        String oldOverStr = dataRecord.getOverTimeStationIdCList();

        // 如果以前就有超时报的数据
        if(StrUtil.isNotBlank(oldOverStr)){
            // 获取以前的超时集合
            List<String> oldOverList = Stream.of(oldOverStr.split(",")).collect(Collectors.toList());
            // 组成新的超时集合
            overList.addAll(oldOverList);
        }
        // 获取缺报集合
        List<String> miss = stationIdList.stream().filter(t-> !real.contains(t)).collect(Collectors.toList());
        // 设置一样数据
        setDataRecord(dataRecord,real,miss,overList);
        updateById(dataRecord);

        // 如果是地面要素
        if("1".equals(editVo.getDataType())){
            // 3表示超时
            surfMinService.badSurf(editVo.getSurfMinList(),"3");
        }

        // 如果是站点状态
        if("2".equals(editVo.getDataType())){
            // 3表示超时
            stationStateService.badState(editVo.getStationStateList(),"3");
        }

        // 推送数据至云端
        postDataRecord(dataRecord);
    }


    @Override
    public List<TBaseDataRecord> missReportByTypeLeHour(String type, int nHour) {
        // 数据类型为空 是啥意思
        if(StrUtil.isBlank(type)){
            return null;
        }
        // 查询所有缺报的
        LambdaQueryWrapper<TBaseDataRecord> lqw = Wrappers.lambdaQuery();
        lqw
                .eq(true,TBaseDataRecord::getDataType,type)
                // 超过1天的不获取
                .ge(true,TBaseDataRecord::getCreateTime, DateUtils.dateTimeMinusHourThe(nHour))
                .gt(true,TBaseDataRecord::getMissReportStationNum,0);

        return list(lqw);
    }

    @Override
    public List<TBaseDataRecord> missReportByTypeLeDay(String type,int day) {
        // 数据类型为空 是啥意思
        if(StrUtil.isBlank(type)){
            return null;
        }
        // 查询所有缺报的
        LambdaQueryWrapper<TBaseDataRecord> lqw = Wrappers.lambdaQuery();
        lqw
                .eq(true,TBaseDataRecord::getDataType,type)
                // 超过1天的不获取
                .ge(true,TBaseDataRecord::getCreateTime, DateUtils.dateTimeMinusDay(day))
                .gt(true,TBaseDataRecord::getMissReportStationNum,0);

        return list(lqw);
    }

    @Override
    public void addDataRecord(DataRecordAddVo addVo) throws IOException {
        // 如果没有获取到上传的集合那就不用管了
        if(addVo==null || addVo.getRealReportStationIdCList().size()==0){
            return;
        }

        TBaseDataRecord dataRecord = new TBaseDataRecord();
        // 设置几个固定的参数
        dataRecord.setDataType(addVo.getDataType());
        dataRecord.setRequestNum(addVo.getRequestNum());
        dataRecord.setTimes(addVo.getTimes());

        // 获取所有站点 IDC 集合
        List<String> stationIdList =  stationInfoService.allStationIdC();
        // 设置应该报的站点数量
        dataRecord.setShouldReportStationNum(stationIdList.size());
        // 获取缺报的数据 然后进行存库
        List<String> miss = stationIdList.stream().filter(t-> !addVo.getRealReportStationIdCList().contains(t)).collect(Collectors.toList());

        // 如果是地面要素
        if("1".equals(addVo.getDataType())){
            List<TBaseSurfMin> surfMinList = new ArrayList<>();
            for (String idc : miss) {
                TBaseSurfMin surfMin = new TBaseSurfMin();
                // 要素类型为2 缺报
                surfMin.setSurfType("2");
                surfMin.setStation_id_c(idc);
                surfMin.setRequestNum(addVo.getRequestNum());
                surfMinList.add(surfMin);
            }
            // 2表示缺报
            surfMinService.badSurf(surfMinList,"2");
        }
        // 如果是状态
        if("2".equals(addVo.getDataType())){
            List<TBaseStationState> stationStateList = new ArrayList<>();
            for (String idc : miss) {
                TBaseStationState stationState = new TBaseStationState();
                // 状态类型为2 缺报
                stationState.setStateType("2");
                stationState.setRequestNum(addVo.getRequestNum());
                stationState.setStationIdC(idc);

                stationStateList.add(stationState);
            }
            // 2表示缺报
            stationStateService.badState(stationStateList,"2");
        }
        // 设置一样数据
        setDataRecord(dataRecord,addVo.getRealReportStationIdCList(),miss,new ArrayList<>());
        // 及时的等于开始就报的
        dataRecord.setInTimeStationNum(dataRecord.getRealReportStationNum());
        dataRecord.setInTimeStationIdCList(dataRecord.getRealReportStationIdCList());
        // 保存入库
        save(dataRecord);
        // 推送数据至云端
        postDataRecord(dataRecord);
    }

    private void setDataRecord(TBaseDataRecord dataRecord,List<String> real,List<String> miss,List<String> over){
        // 设置实到的站点数量
        dataRecord.setRealReportStationNum(real.size());
        // 设置缺报的站点数量 等于 实到减去缺报
        dataRecord.setMissReportStationNum(miss.size());
        // 设置超时报的站点数量 默认为0
        dataRecord.setOverTimeStationNum(over.size());
        // 设置实报的站点 并且以逗号隔开
        dataRecord.setRealReportStationIdCList(String.join(",", real));
        // 设置缺报的站点 并且以逗号隔开
        dataRecord.setMissReportStationIdCList(String.join(",", miss));
        // 设置超时的站点 并且以逗号隔开
        dataRecord.setOverTimeStationIdCList(String.join(",", over));
    }
}
